﻿#region 
/*---------------------------------------------------------------- 
* 项目名称 ：Mrc.Application.Sercvice 
* 项目描述 ： 
* 类 名 称 ：IAccountService 
* 类 描 述 ： 
* 所在的域 ：DESKTOP-HKKGEJ7
* 命名空间 ：Mrc.Application.Sercvice
* 机器名称 ：DESKTOP-HKKGEJ7 
* CLR 版本 ：4.0.30319.42000 
* 作 者 ：mrc 
* 创建时间 ：2019/2/16 23:42:15 
* 更新时间 ：2019/2/16 23:42:15 
* 版 本 号 ：v1.0.0.0 
******************************************************************* 
* Copyright @ mrc 2019. All rights reserved. *******************************************************************
 //----------------------------------------------------------------*/
#endregion

using Mrc.Data;
using System;
using System.Collections.Generic;
using System.Text;
using Mrc.Entity;
using Chloe;
using System.Linq.Expressions;
using DotNetEx;
using DotNetEx.ExceptionEx;

namespace Mrc.Application
{
    public interface IAccountService : IServiceBase<SysUser>, IMrcService
    {
        bool CheckLogin(string userName, string password, out SysUser user, out string msg);
        void ChangePassword(string userId, string oldPassword, string newPassword);
    }
    public class AccountService : ServiceBase<SysUser>, IAccountService
    {
        public AccountService(IDbContext dbContext, IServiceProvider services) : base(dbContext, services)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="password">前端传过来的是经过md5加密后的密码</param>
        /// <param name="user"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool CheckLogin(string loginName, string password, out SysUser user, out string msg)
        {
            user = null;
            msg = null;
            dnUtils.IsNullOrEmptyMrc(loginName,"登录名不能为空");
            dnUtils.IsNullOrEmptyMrc(password,"密码不能为空");
            var view = this.DbContext.JoinQuery<SysUser, SysUserLogOn>((u, userLogOn) => new object[]
            {
                JoinType.InnerJoin,u.Id == userLogOn.UserId
            })
            .Select((u, userLogOn) => new { User = u, UserLogOn = userLogOn });

            loginName = loginName.ToLower();
            if (MrcUtils.IsMobilePhone(loginName))
            {
                view = view.Where(a => a.User.MobilePhone == loginName);
            }
            else if (MrcUtils.IsEmail(loginName))
            {
                view = view.Where(a => a.User.Email == loginName);
            }
            else
            {
                view = view.Where(a => a.User.AccountName == loginName);
            }

            view = view.Where(a => a.User.State != AccountState.Closed);

            var viewEntity = view.FirstOrDefault();

            if (viewEntity == null)
            {
                msg = "账户不存在，请重新输入";
                return false;
            }
            if (!viewEntity.User.IsAdmin())
            {
                if (viewEntity.User.State == AccountState.Disabled)
                {
                    msg = "账户被禁用，请联系管理员";
                    return false;
                }
            }

            SysUser userEntity = viewEntity.User;
            SysUserLogOn userLogOnEntity = viewEntity.UserLogOn;

            string dbPassword = EncryptHelper.EncryptMD5Password(password, userLogOnEntity.UserSecretkey);
            if (dbPassword != userLogOnEntity.UserPassword)
            {
                msg = "密码不正确，请重新输入";
                return false;
            }

            DateTime lastVisitTime = DateTime.Now;
            this.DbContext.Update<SysUserLogOn>(a => a.Id == userLogOnEntity.Id, a => new SysUserLogOn() { LogOnCount = a.LogOnCount + 1, PreviousVisitTime = userLogOnEntity.LastVisitTime, LastVisitTime = lastVisitTime });
            user = userEntity;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="oldPassword">明文</param>
        /// <param name="newPassword">明文</param>
        public void ChangePassword(string userId, string oldPassword, string newPassword)
        {
            SysUserLogOn userLogOn = this.DbContext.Query<SysUserLogOn>().Where(a => a.UserId == userId).First();
            string encryptedOldPassword = EncryptHelper.DesEncrypt(oldPassword, userLogOn.UserSecretkey);
            if (encryptedOldPassword != userLogOn.UserPassword)
                throw new InvalidInputException("旧密码不正确");

            string newUserSecretkey = UserHelper.GenUserSecretkey();
            string newEncryptedPassword = EncryptHelper.DesEncrypt(newPassword, newUserSecretkey);

            this.DbContext.DoWithTransaction(() =>
            {
                this.DbContext.Update<SysUserLogOn>(a => a.UserId == userId, a => new SysUserLogOn() { UserSecretkey = newUserSecretkey, UserPassword = newEncryptedPassword });
                //this.Log(LogType.Update, "Account", true, "用户[{0}]修改密码".ToFormat(userId));
            });
        }
    }
}

